package com.oneinlet.server.handler

import com.oneinlet.AppConf
import com.oneinlet.Constant
import com.oneinlet.Pandora
import com.oneinlet.server.ServerChannelManage
import io.netty.buffer.Unpooled
import io.netty.channel.*
import io.netty.handler.timeout.IdleState
import io.netty.handler.timeout.IdleStateEvent
import org.slf4j.LoggerFactory

/**
 * Created by WangZiHe on 2019/1/7/007
 * QQ/WeChat:648830605
 * QQ-Group:368512253
 * Blog:www.520code.net
 * Github:https://github.com/yancheng199287
 */

class YCServerHandler : SimpleChannelInboundHandler<Pandora>() {
    private val logger = LoggerFactory.getLogger(this.javaClass)

    override fun channelActive(ctx: ChannelHandlerContext?) {
    }


    override fun channelRead0(ctx: ChannelHandlerContext, pandora: Pandora) {
        when (pandora.msgType) {
            Pandora.MsgType.HEARTBEAT_PACKET.type -> {
                logger.debug("收到客户端的心跳数据包")
            }
            Pandora.MsgType.REQUEST_AUTH.type -> {
                authentication(ctx, pandora)
            }
            // 从YClient发送的请求消息  可以转发到用户端
            Pandora.MsgType.SEND_MSG_FROM_YCLINET_TO_YCSERVER.type -> {
                val channel = ServerChannelManage.getAppChannel(pandora.channelId)
                if (channel == null) {
                    logger.debug("用户端的通道已经断开，无需发送响应消息！")
                    return
                }
                channel.writeAndFlush(Unpooled.copiedBuffer(pandora.data))
            }

            // 客户端主动申请断开连接请求
            Pandora.MsgType.DISCONNECT_FROM_YCLINET_TO_YCSERVER.type -> {
            }
            else -> {
                logger.warn("YCServer 接收到不可识别的消息")
            }

        }
    }


    override fun channelInactive(ctx: ChannelHandlerContext?) {
        logger.error("YClient通道无效断开")
    }

    override fun exceptionCaught(ctx: ChannelHandlerContext?, cause: Throwable?) {
        logger.error("YClient通道异常关闭", cause)
    }

    /***
     *
     * **/
    /***
     *  对客户端进行鉴权操作，判断连接通信密钥是否正确
     * **/
    fun authentication(ctx: ChannelHandlerContext, pandora: Pandora) {
        if (AppConf.accessKey == pandora.content) {
            logger.info("恭喜，认证成功！")
            pandora.content = "恭喜你，认证成功!"
            pandora.msgType = Pandora.MsgType.SUCCESS_AUTH.type
            ServerChannelManage.YClientChannel = ctx.channel()
            ServerChannelManage.YClientChannel.writeAndFlush(pandora)
        } else {
            logger.info("认证失败 ！")
            pandora.content = "很抱歉，认证失败!"
            pandora.msgType = Pandora.MsgType.FAILED_AUTH.type
            ctx.writeAndFlush(pandora).addListener(ChannelFutureListener.CLOSE)
        }
    }

    override fun userEventTriggered(ctx: ChannelHandlerContext?, event: Any?) {
        if (event is IdleStateEvent) {
            //  logger.info("心跳检测事件触发，可能断线，触发重连机制 ${event.state()}")
            when {
                /*服务端这边一直未收到客户端发来的心跳数据包，那么就读超时，关闭客户端连接*/
                event.state() == IdleState.READER_IDLE -> {
                    // logger.warn("===服务器端===(READER_IDLE 读超时)")
                    ServerChannelManage.YClientChannel.close()
                }
                event.state() == IdleState.WRITER_IDLE -> {
                    // logger.warn("===服务器端===(WRITER_IDLE 写超时)")
                    ServerChannelManage.YClientChannel.writeAndFlush(Constant.makeHeartBeatPack(ctx!!.channel().id().asLongText()))
                }
                event.state() == IdleState.ALL_IDLE -> {
                    // logger.warn("===服务器端===(ALL_IDLE 总超时)")
                    return
                }
            }
        }
    }
}